/*******************************************************************************
*   Copyright (C) Harbin Institute of Technology, Shenzhen.
*				  All Rights Reserved.
*   Department: Decoration
********************************************************************************
* File Name   : encoder.c
* Author      : Dayuan
* Version     : v0.01
* Date        : 2019/9/5
* Description : Decoration Rototics Manipulator task.
*******************************************************************************/
/*-History----------------------------------------------------------------------
* Version   Date      Name        Changes and comments
* v0.01     2019/9/5  Dayuan    initial version
*=============================================================================*/
/* System Includes -----------------------------------------------------------*/

/* Public Includes -----------------------------------------------------------*/
#include "tim.h"
#include "gpio.h"
#include "std.h"
/* Private Includes ----------------------------------------------------------*/
#include "encoder.h"
#include "encoder_if.h"
/* Global variables ----------------------------------------------------------*/
ENC_INC_INFO enc_inc;
/* Private variables ---------------------------------------------------------*/


/* Global functions ----------------------------------------------------------*/
/**
  * @brief  encoder module init.
  * @param  None
  * @retval None
  */
void enc_reset_create(void)
{
	/* Start the encoder interface */
  HAL_TIM_Encoder_Start(&htim8, TIM_CHANNEL_ALL);
	
	enc_inc.valid = 0;
	enc_inc.scaled = 0;
	enc_inc.cpr = ENC_INC_CPR;
	enc_inc.gear_ratio = GEAR_RATIO;
	enc_inc.total_cnt = ENC_INC_TOTAL_CNT;
}
/**
  * @brief  increment encoder counter calculate when counter more than perioid val.
  * @param  no: increment encoder number type.
  * @retval tim actual counter value.
  */
void encoder_polling(void)
{
	mcu_disable_interrupt();
	enc_inc.cur_cnt = enc_get_cnt();
	enc_inc.dir = enc_get_dir();
	mcu_enable_interrupt();
	
	if(enc_inc.dir == ENC_INC_CW)	/* counter increase*/
	{
		if(enc_inc.cur_cnt < enc_inc.last_cnt)
		{
			enc_inc.turn++;
			if(enc_inc.turn >= enc_inc.gear_ratio)
			{
				enc_inc.turn = 0;
			}
		}
	}
	else
	{
		if(enc_inc.cur_cnt > enc_inc.last_cnt)
		{
			enc_inc.turn--;
			if(enc_inc.turn < 0)
			{
				enc_inc.turn = enc_inc.gear_ratio - 1;
			}
		}
	}

	enc_inc.scaled = enc_inc.cpr*4*enc_inc.turn + enc_inc.cur_cnt;
	enc_inc.last_cnt = enc_inc.cur_cnt;
	enc_inc.angle = ((float)enc_inc.scaled/enc_inc.total_cnt) * 360;
}

/**
  * @brief  increment encoder counter z signal handle.
  * @param  no: increment encoder number type.
  * @retval tim actual counter value.
  */
void enc_inc_z_exit_handle(void)
{
	enc_inc.cur_cnt = enc_get_cnt();
	enc_inc.dir = enc_get_dir();
	if(enc_inc.dir == ENC_INC_CW)	/* counter increase*/
	{
		if(enc_inc.cur_cnt < enc_inc.last_cnt)
		{
			enc_inc.turn++;
			if(enc_inc.turn >= enc_inc.gear_ratio)
			{
				enc_inc.turn = 0;
			}
		}
	}
	else
	{
		if(enc_inc.cur_cnt > enc_inc.last_cnt)
		{
			enc_inc.turn--;
			if(enc_inc.turn < 0)
			{
				enc_inc.turn = enc_inc.gear_ratio - 1;
			}
		}
		
	}

	enc_inc.scaled = enc_inc.cpr*4*enc_inc.turn + enc_inc.cur_cnt;
	enc_inc.last_cnt = enc_inc.cur_cnt;
	enc_inc.z_cnt = enc_inc.scaled;
}

void enc_inc_calibration(void)
{
	enc_inc.valid = 1;
	enc_inc.cur_cnt = 0;
	enc_inc.last_cnt = 0;
	enc_inc.turn = 0;

	__HAL_TIM_SET_COUNTER(&htim8,0);
	
}

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  get tim cnt for encoder count.
  * @param  None: increment encoder number type.
  * @retval tim counter value.
  */
uint32_t enc_get_cnt(void)
{
	return __HAL_TIM_GET_COUNTER(&htim8);
}

/**
  * @brief  increment encoder tim init.
  * @param  no: increment encoder number type.
  * @retval tim counter value.
  */
ENC_INC_DIR_TYPE enc_get_dir(void)
{
	uint8_t ret;

	ret = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim8);

	if(ret == FALSE)
	{
		return ENC_INC_CW;
	}
	else
	{
		return ENC_INC_CCW;
	}
}
/****************************** END OF FILE ***********************************/
